package com.flower.controller.common;

import com.flower.domain.dto.EmailDto;
import com.flower.domain.dto.LoginDto;
import com.flower.domain.dto.LogoutDto;
import com.flower.domain.entity.Admin;
import com.flower.domain.entity.Buyer;
import com.flower.domain.entity.Farmer;
import com.flower.constans.FrontendType;
import com.flower.properties.JwtProperties;
import com.flower.service.AdminService;
import com.flower.service.BuyerService;
import com.flower.service.FarmerService;
import com.flower.utils.AjaxResult;
import com.flower.utils.JwtUtil;
import com.flower.utils.Md5Util;
import com.flower.utils.UserContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

import static com.flower.utils.AjaxResult.error;
import static com.flower.utils.AjaxResult.success;

/**
 * 三端共用登录信息
 */
@Slf4j
@RestController
@RequestMapping("/account")
public class AccountController {

    @Autowired
    private FarmerService farmerService;
    @Autowired
    private AdminService adminService;
    @Autowired
    private BuyerService buyerService;
    @Autowired
    private JwtProperties jwtProperties;
    @Autowired
    private StringRedisTemplate redisTemplate;

    /**
     * 花农登录
     * @param loginDto
     * @return
     */
    @PostMapping("/loginFarmer")
    public AjaxResult loginFarmer(@RequestBody LoginDto loginDto) {
        Farmer farmer = farmerService.login(loginDto);
        // 返回登录结果
        if (farmer != null) {
            // 登录成功，生成JWT令牌
            Map<String, Object> claims = new HashMap<>();
            claims.put("FarmerId", farmer.getFarmerId());

            // 生成token
            String token = JwtUtil.createJWT(
                    jwtProperties.getSecretKey(),
                    jwtProperties.getTtl(),
                    claims
            );
            // 将token根据用户id存入redis
            redisTemplate.opsForValue().set("loginFarmer:" + farmer.getFarmerId(), token);
            HashMap<String, Object> map = new HashMap<>();
            map.put("token", token);
            map.put("farmerId", farmer.getFarmerId());
            return success("登录成功", map);
        } else {
            return error("账号或密码错误");
        }
    }

    /**
     * 管理员登录
     * @param loginDto
     * @return
     */
    @PostMapping("/loginAdmin")
    public AjaxResult loginAdmin(@RequestBody LoginDto loginDto) {
        Admin admin = adminService.login(loginDto);
        // 返回登录结果
        if (admin != null) {
            // 登录成功，生成JWT令牌
            Map<String, Object> claims = new HashMap<>();
            claims.put("AdminId", admin.getAdminId());

            // 生成token
            String token = JwtUtil.createJWT(
                    jwtProperties.getSecretKey(),
                    jwtProperties.getTtl(),
                    claims
            );
            // 将token根据用户id存入redis
            redisTemplate.opsForValue().set("loginAdmin:" + admin.getAdminId(), token);
            HashMap<String, Object> map = new HashMap<>();
            map.put("token", token);
            map.put("adminId", admin.getAdminId());
            return success("登录成功", map);
        } else {
            return error("账号或密码错误");
        }
    }

    /**
     * 购买者登录
     * @param loginDto
     * @return
     */
    @PostMapping("/loginBuyer")
    public AjaxResult loginBuyer(@RequestBody LoginDto loginDto) {
        Buyer buyer = buyerService.login(loginDto);
        // 返回登录结果
        if (buyer != null) {
            // 登录成功，生成JWT令牌
            Map<String, Object> claims = new HashMap<>();
            claims.put("BuyerId", buyer.getBuyerId());

            // 生成token
            String token = JwtUtil.createJWT(
                    jwtProperties.getSecretKey(),
                    jwtProperties.getTtl(),
                    claims
            );
            // 将token根据用户id存入redis
            redisTemplate.opsForValue().set("loginBuyer:" + buyer.getBuyerId(), token);
            HashMap<String, Object> map = new HashMap<>();
            map.put("token", token);
            map.put("buyerId", buyer.getBuyerId());
            map.put("buyerType", buyer.getBuyerType());
            return success("登录成功", map);
        } else {
            return error("账号或密码错误");
        }
    }

    /**
     * 退出登录
     * @return
     */
    @GetMapping("/logout")
    public AjaxResult logout() {
        String frontendType = UserContext.getFrontendType();
        Long userId = UserContext.getUserId();
        // 根据用户id删除redis中的token
        redisTemplate.delete("login"+ frontendType +":" + userId);
        return success("退出成功,欢迎下次光临哟~");
    }

    /**
     * 重置密码
     * @param emailDto
     * @return
     */
    @PutMapping("/reset")
    public AjaxResult reset(@RequestBody EmailDto emailDto) {
        //从redis中获取邮箱的captcha
        String captcha = redisTemplate.opsForValue().get("resetPasswordCaptcha-"+ emailDto.getFrontendType()+":" + emailDto.getEmail());
        //判断验证码是否正确
        if (!captcha.equals(emailDto.getCaptcha())) {
            return error("验证码错误");
        }

        // 先声明角色实体
        //根据邮箱查询用户信息
        if(emailDto.getFrontendType().equals(FrontendType.TYPE_ADMIN)){
            Farmer farmer = farmerService.findFarmerByEmail(emailDto.getEmail());
            if (farmer == null) {
                return error("邮箱还未注册，请注册");
            }
            // 密码加密
            farmer.setPassword(Md5Util.getMD5String(emailDto.getNewPassword()));
            farmerService.updateById(farmer);
        }else if (emailDto.getFrontendType().equals(FrontendType.TYPE_BUYER)){
            Buyer buyer = buyerService.findBuyerByEmail(emailDto.getEmail());
            if (buyer == null) {
                return error("邮箱还未注册，请注册");
            }
            // 密码加密
            buyer.setPassword(Md5Util.getMD5String(emailDto.getNewPassword()));
            buyerService.updateById(buyer);
        } else if (emailDto.getFrontendType().equals(FrontendType.TYPE_ADMIN)) {
            Admin admin = adminService.findAdminByEmail(emailDto.getEmail());
            if (admin == null) {
                return error("邮箱还未注册，请注册");
            }
            // 密码加密
            admin.setPassword(Md5Util.getMD5String(emailDto.getNewPassword()));
            adminService.updateById(admin);
        }
        return success("重置密码成功！");
    }

    /**
     * 通过邮箱进行登录和注册
     * @param emailDto
     * @return
     */
    @PostMapping("/intoByEmail")
    public AjaxResult intoByEmail(@RequestBody EmailDto emailDto) {
        //从redis中获取邮箱的captcha
        String captcha = redisTemplate.opsForValue().get("captcha-"+ emailDto.getFrontendType()+":" + emailDto.getEmail());
        //判断验证码是否正确
        if (!captcha.equals(emailDto.getCaptcha())) {
            return error("验证码错误");
        }
        Map<String, Object> claims = new HashMap<>();
        HashMap<String, Object> map = new HashMap<>();
        //根据邮箱查询用户信息
        if (emailDto.getFrontendType().equals(FrontendType.TYPE_FARMER)){
            Farmer farmer = farmerService.findFarmerByEmail(emailDto.getEmail());
            // 如果用户不存在，则进行注册
            if (farmer == null) {
                Farmer newFarmer = new Farmer();
                BeanUtils.copyProperties(emailDto, newFarmer);
                farmerService.save(newFarmer);
                //注册成功后，获取用户信息
                farmer = farmerService.findFarmerByEmail(emailDto.getEmail());
            }
            // 登录成功后，生成jwt令牌
            claims.put("FarmerId", farmer.getFarmerId());
            // 设置token
            String token = JwtUtil.createJWT(jwtProperties.getSecretKey(), jwtProperties.getTtl(), claims);
            // 将token根据用户id存入redis
            redisTemplate.opsForValue().set("loginFarmer:" + farmer.getFarmerId(), token);
            map.put("token", token);
            map.put("farmerId", farmer.getFarmerId());
        }else if (emailDto.getFrontendType().equals(FrontendType.TYPE_BUYER)){
            Buyer buyer = buyerService.findBuyerByEmail(emailDto.getEmail());
            // 如果用户不存在，则进行注册
            if (buyer == null) {
                Buyer newBuyer = new Buyer();
                BeanUtils.copyProperties(emailDto, newBuyer);
                buyerService.save(newBuyer);
                //注册成功后，获取用户信息
                buyer = buyerService.findBuyerByEmail(emailDto.getEmail());
            }
            // 登录成功后，生成jwt令牌
            claims.put("BuyerId", buyer.getBuyerId());
            // 设置token
            String token = JwtUtil.createJWT(jwtProperties.getSecretKey(), jwtProperties.getTtl(), claims);
            // 将token根据用户id存入redis
            redisTemplate.opsForValue().set("loginBuyer:" + buyer.getBuyerId(), token);
            map.put("token", token);
            map.put("buyerId", buyer.getBuyerId());
            map.put("buyerType", buyer.getBuyerType());
        }else if(emailDto.getFrontendType().equals(FrontendType.TYPE_ADMIN)){
            Admin admin = adminService.findAdminByEmail(emailDto.getEmail());
            // 如果用户不存在，则进行注册
            if (admin == null) {
                Admin newAdmin = new Admin();
                BeanUtils.copyProperties(emailDto, newAdmin);
                adminService.save(newAdmin);
                //注册成功后，获取用户信息
                admin = adminService.findAdminByEmail(emailDto.getEmail());
            }
            // 登录成功后，生成jwt令牌
            claims.put("AdminId", admin.getAdminId());
            // 设置token
            String token = JwtUtil.createJWT(jwtProperties.getSecretKey(), jwtProperties.getTtl(), claims);
            // 将token根据用户id存入redis
            redisTemplate.opsForValue().set("loginAdmin:" + admin.getAdminId(), token);
            map.put("token", token);
            map.put("adminId", admin.getAdminId());
        }
        return success("登录成功", map);
    }
}
